#include"threadpool.h"

#include<sys/time.h>
#include<unistd.h>

void threadpool::tmp(void* arg)
{
    threadpool* tmp = static_cast<threadpool*>(arg);
    tmp->RunInto();
}

void threadpool::start()
{
    runing_ = true;
    threads_.reserve(ThreadNums_);
    for(int i = 0; i < ThreadNums_;i++)
    {
        Task sk = std::bind(threadpool::tmp, static_cast<void*>(this));
        threads_.push_back(std::unique_ptr<std::thread>(new std::thread(std::move(sk))));
    }
}

void threadpool::add(Task sk)
{
    if(queue_.size() >= MaxQuestSize_)
    {
        MutexLockGuard lock(mutex_);
        while(queue_.size() >= MaxQuestSize_&&runing_)
            notFull_.wait();
        if(runing_)
        {
            queue_.push_back(std::move(sk));
            notEmpty_.notify();
        }
    }
    else if(runing_)
    {
        queue_.push_back(std::move(sk));
        notEmpty_.notify();
    }
}

threadpool::Task threadpool::task()
{
    MutexLockGuard lock(mutex_);
    while(queue_.empty() && runing_)
        notEmpty_.wait();
    Task sk;
    if(!queue_.empty())
    {
        sk = queue_.front();
        queue_.pop_front();
        if(MaxQuestSize_ > 0)
            notFull_.notify();
    }
    return sk;
}

void threadpool::RunInto()
{
    assert(runing_);
    while(runing_)
    {
        try
        {
            Task sk(task());

            struct timeval tv;
            struct timezone tz;
            gettimeofday(&tv,&tz);

            if(sk)
                sk();

            struct timeval tv1;
            struct timezone tz1;
            gettimeofday(&tv1,&tz1);
            static long long text;
            text += (tv1.tv_sec-tv.tv_sec)*1000000+(tv1.tv_usec-tv.tv_usec);
            static long nums;

            printf("每次请求处理平均时间：%ld 微秒 处理请求次数：%ld 线程数：15\n", text/++nums, nums);            
        }
        catch(...)
        {
            printf("there is a error\n");
        }
    }
}